<?php
include_once("robot.php");

$towns_filename            = false;
$population_count_filename = false;
$message_template          = false;
$wikification_message      = false;
$force_year_update         = false;
$no_wikification           = true;
$density_message           = false;
$simulate                  = true;
$year                      = false;
$alternate_config          = false;
$template_to_use           = "Infobox Communes de France";
$time_between_update       = 5;

if(!isset($max_edit_count))
  $max_edit_count = 1;

function usage($msg = false) {
  print "
Hi ! My name is DroopigBot. I'm a wikipedia robot which is capable to update population
count in town articles.

To do my work, I'm need to have two files :
- one for towns article name
- another with population count by town


Usage for DroopigBot :

  -h  --help                           Display this message then exit
      --no-simulation                  Write for real modification. USE THIS WITH CARE !!!
      --fast-edit                      No sleep between 2 updates
      --sleep <COUNT>                  sleep <COUNT> seconds between 2 updates.
      --town-listing <FILE>            Use <FILE> as town listing
      --population-listing <FILE>      Use <FILE> as population listing
      --alternate-config <CONFIG>      Use file config-<CONFIG>.inc.php instead of config.inc.php
      --message-template '<MSG>'       Use '<MSG>' as update messages
      --density-msg '<MSG>'            Use '<MSG>' as message when changing density
      --year-wikification-msg '<MSG>'  Message to use if not updating population but wikifying year (ie: 2006 -> [[2006])
      --wikify_year                    Wikify year (no wikification by default)
      --force-year-update              Update year of update even if no change on population count
      --edit-count <COUNT>             Set max edition count to <COUNT> (0 = no limitation)
      --year <YEAR>                    Use <YEAR> as year of the update
      --verbose                        Verbose mode

$msg
";
}

for($i = 1; $i < count($argv) ; $i++) {
  if($argv[$i] == "--help" || $argv[$i] == "-h") {
    usage(); exit(0);
  } else if($argv[$i] == "--fast-edit") {
    $time_between_update = 0;
  } else if($argv[$i] == "--sleep") {
    $time_between_update = $argv[++$i];
  } else if($argv[$i] == "--town-listing") {
    $towns_filename = $argv[++$i];
  } else if($argv[$i] == "--population-listing") {
    $population_count_filename = $argv[++$i];
  } else if($argv[$i] == "--year") {
    $year = $argv[++$i];
  } else if($argv[$i] == "--force-year-update") {
    $force_year_update = true;
  } else if($argv[$i] == "--wikify-year") {
    $no_wikification = false;
  } else if($argv[$i] == "--max-edit-count") {
    $max_edit_count = $argv[++$i];
  } else if($argv[$i] == "--message-template") {
    $message_template = $argv[++$i];
  } else if($argv[$i] == "--density-msg") {
    $density_message = $argv[++$i];
  } else if($argv[$i] == "--year-wikification-msg") {
    $wikification_message = $argv[++$i];
  } else if($argv[$i] == "--edit-count") {
    $max_edit_count = $argv[++$i];
  } else if($argv[$i] == "--alternate-config") {
    $alternate_config = $argv[++$i];
  } else if($argv[$i] == "--no-simulation") {
    $simulate = false;
  } else if($argv[$i] == "--verbose") {
    $verbose = true;
  } else {
    print "Error : unknown option '".$argv[$i]."'\n"; exit(1);
  }
}

if(!$alternate_config) {
  include_once("config.inc.php");
} else {
  include_once("config-$alternate_config.inc.php");
}

if(!$year || !preg_match("/20\d{2}/", $year)) {
  usage("Please specify year of the numbers (format : YYYY). Ex : --year 2006");
  exit(1);
}

if(!$simulate)
  $robot->activateWrite();

if($verbose)
  $robot->setVerbose();

if(!preg_match("/^\d+$/", $max_edit_count)) {
  usage("Error while checking max edit count : bad value ($max_edit_count)");
  exit(1);
}

if(strlen($message_template) == 0) {
  usage("Message template is empty => exiting (--message-template '<MSG>')");
  exit(1);
}

if(!$no_wikification && !$wikification_message) {
  usage("Wikification message is empty => exiting (--year-wikification-msg '<MSG>')");
  exit(1);
}

if(!$density_message) {
  usage("density message is empty => exiting (--density-msg '<MSG>')");
  exit(1);
}

// Verification des fichiers de population + villes
if(file_exists($towns_filename)) {
  print "Loading towns name\n";
  $towns = file($towns_filename, FILE_IGNORE_NEW_LINES);
} else {
  usage("File for town listing '$town_file' does not exist");
  exit(1);
}

if(file_exists($population_count_filename)) {
  print "Loading population count by town\n";
  $population_file_content = file($population_count_filename, FILE_IGNORE_NEW_LINES);
} else {
  usage("File for population count '$population_count_filename' does not exist");
  exit(1);
}

$population_count = array();
$town_count = array();

$to_replace = array(" (charente-maritime)" => "",
                    " sur gironde" => "",
                    " (charente)" => "",
                    " (france)" => "",
                    "É" => "e",
                    "è" => "e",
                    "à" => "a",
                    "' " => "'",
                    "-" => " ",
                    "_" => " ",
                    "œ" => "oe");

// Chargement du fichier de la population et verification de l'absence de doublon
print "Parsing population count\n";
foreach($population_file_content as $line) {
  $pop = array();
  if(preg_match("/\"(.+)\",([\xC2\xA0\s\d]+)/", $line, $pop)) {
    $reduced_town_name = str_replace(array_keys($to_replace), array_values($to_replace), strtolower($pop[1]));
    if(array_key_exists($reduced_town_name, $population_count)) {
      print "Town $reduced_town_name already exist\n"; exit(1);
    }
    $population_count[$reduced_town_name] = str_replace(array(" ", "\xC2", "\xA0"), array("", "", ""), $pop[2]);
  }
}

// Pré-vérification des données avant essai de modification
print "Checking data integrity between town and population count\n";
foreach($towns as $town) {
  $reduced_town_name = str_replace(array_keys($to_replace), array_values($to_replace), strtolower($town));
  if(array_key_exists($reduced_town_name, $population_count)) {
    print ".";
    $town_count[$town] = $population_count[$reduced_town_name];
  } else {
    print "Error while trying to find population count for town '$town'\n";
    exit(1);
  }
}
print "\nGood news ! Population count seems fine (".count($towns)." towns).\n";

// Mise à jour des communes en fonction du fichier de la population de Charente.
$edit_count = 0;
foreach($towns as $town) {
  $current_message = $message_template;
  print "Processing '$town' in progress ... ";
  // MAJ cache + chargement du contenu du cache
  print " cache";
  $robot->updateCache($town);
  $town_content = $robot->getCache($town);
  $cache_filename = $robot->getCacheName($town);
  // Verification sur la taille de l'article
  print " content";
  if(preg_match("/^#REDIRECT/", $town_content)) {
    print "\nTown '$town' is not an article but a redirection => exiting\n";
    exit(1);
  }
  if(strlen($town_content) < 100) {
    print "\nSomething is strange : town article is too small for '$town' => exiting\n";
    exit(1);
  }
  // Lancement MAJ population
  $replace_count = 0; $new_content = $town_content;
  // Construction RE population
  $population_split = preg_split('//', $town_count[$town], -1, PREG_SPLIT_NO_EMPTY);
  $population_re = implode("(\s|&nbsp;)?", $population_split);
  $need_to_update_population = !preg_match("/\| *sans *= *$population_re( *|$)/", $new_content);
  if($need_to_update_population || $force_year_update) {
    // RE pour l'annee
    $year_split = preg_split('//', $year, -1, PREG_SPLIT_NO_EMPTY);
    $year_re = "\[{0,2}".implode("\s?", $year_split)."\]{0,2}";
    $need_to_update_year = !preg_match("/(\| *date-sans *= *)$year_re */", $new_content);
  }
  if(!$need_to_update_year && !$need_to_update_population) {
    print "\nNothing to do for '$town'\n";
    continue;
  }
  print "\n * Updating article for '$town'.\n";
  if($need_to_update_year)
    $new_content = preg_replace("/(\| *date-sans *= *)(.+)?/", "\${1}$year", $new_content);
  if($need_to_update_population) {
    $new_content = preg_replace("/(\| *sans *= *)(\d([\d ]|\&nbsp;)+)( *|$)/", "\${1}".$town_count[$town], $new_content);
    if(!preg_match("/{{Infobox Communes de France/", $new_content)) {
      print "Warning : Current template for '$town' is not up to date\n";
      if(preg_match("/\| *dens *= *([\d ]+)?/", $new_content, $cur_dens)) {
        if(!$cur_dens[1] || !preg_match("/\| *km² *= *([\d ,]+)/", $new_content, $area)) {
          print "Cannot compute density for '$town'. Skipping...\n"; continue;
        }
        $real_area = str_replace(array(" ", ","), array("","."), $area[1]) + 0;
        $density = round($town_count[$town] / $real_area);
        if($density != $cur_dens[1]) {
          print " * Updating density (population = ".$town_count[$town]." / area = $real_area).\n";
          print " => new density : $density (old : ".$cur_dens[1].")\n";
          $new_content = preg_replace("/(\| *dens *= *)(\d[\d ,.]+)/", "\${1}$density", $new_content);
          $current_message .= " + $density_message";
        }
      } else {
        print "Cannot update density.\n"; exit(1);
      }
    } else {
      print "Good ! '$town' use '$template_to_use' template.\n";
      if(preg_match("/\| *dens *= *([\d ]+)/", $new_content, $cur_dens) && preg_match("/\|km² *= *([\d ,]+)/", $new_content, $area)) {
        print "Warning ! '$town' use 'dens' field with the template '$template_to_use' => dropping 'dens' field\n";
        $new_content = preg_replace("/(\| *dens *= *)(\d[\d ,.]+)/", "", $new_content);
      }
    }
  }
  $file = fopen("$cache_filename.new", "w");
  fwrite($file, $new_content);
  fclose($file);
  $diff_result = array();
  exec("diff \"$cache_filename\" \"$cache_filename.new\" | egrep -e '^(>|<) '", $diff_result);
  if(count($diff_result) == 0) {
    print "You should not be here (\"$cache_filename\" are equal to \"$cache_filename.new\")\n";
    exit(1);
  }
  if(count($diff_result) <= 6) {
    print "\n ** Need to update article '$town' ($current_message):\n";
    print join("\n", $diff_result)."\n";
    if(!$simulate) {
      exec("mv -f \"$cache_filename.new\" \"$cache_filename\" ");
      $robot->setCurrentModification($current_message);
      $robot->updateArticle($town);
    }
    if(++$edit_count >= $max_edit_count && $max_edit_count > 0) {
      print "Max edit count reach ($edit_count)\n";
      exit(0);
    } else {
      if($max_edit_count > 0)
        print "Edit count = $edit_count (max : $max_edit_count)\n";
    }
  } else if(count($diff_result) > 0) {
    print "Error while trying to update value for article '$town' : to much difference\n";
    print join("\n", $diff_result)."\n";
    exit(1);
  }
  sleep($time_between_update);
}
?>
